package br.mcaslib.swiz.controller
{
	import br.mcaslib.common.Util;
	import br.mcaslib.swiz.event.ListObjNameIdEvent;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ListCollectionView;
	import mx.rpc.AsyncToken;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.RemoteObject;
	
	import spark.components.List;

	/**
	 * Controlador genérico para lidar com collections que possuem basicamente
	 * dois tipos de campos (Id,Name). Esse tipo de collection é muito usado
	 * para popular campos do tipo combobox.
	 */
	public class ListObjNameIdController extends BaseController 
	{
		//--------------------------------------------------------------------------
		//
		//  Constructor
		//
		//--------------------------------------------------------------------------
		
		public function ListObjNameIdController(modelName:String=null,aliasName:String=null,managerName:String=null) {
			super();
			this.modelName = modelName;
			this.aliasName = aliasName;
			if( managerName ) {
				this.managerName = managerName;
			}
		}
		
		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------
		
		[Inject(source='listService')]
		public var listService:RemoteObject;
		
		public var modelName:String;
		
		public var aliasName:String;
		
		[Bindable]
		public var collection:ArrayCollection;
		
		/**
		 * Filtro padrao a ser aplicado sempre que nenhum filtro for
		 * passado como parametro
		 */
		public var defaultFilter:Object;
		
		/**
		 * Nome do manager no lado do servidor
		 */
		public var managerName:String = 'objects';
		
		
		//--------------------------------------------------------------------------
		//
		//  Methods
		//
		//--------------------------------------------------------------------------
		
		/**
		 * Carrega a collection usando o valor do campo de outro objeto como filtro
		 * 
		 * No lado do servidor a query deve ser algo parecido com isso
		 * WHERE <filterField> = <obj[field]>
		 * 
		 * @param obj Objeto
		 * @param field Campo do objeto que deve ser usado como filtro.
		 * @param filterField Campo do filtro que deve ser aplicado no lado do servidor
		 */
		public function loadFromObject( obj:Object, field:String, filterField:String ):AsyncToken {
			var result:AsyncToken = null;
			var value:Object = Util.getValuePropertieFromObj( obj, field );
			if( value ) {
				var objFilter:Object = new Object();
				objFilter[filterField] = value;
				result = this.load( objFilter );
			} else {
				this.empty();
			}
			return result;
		}
		
		/**
		 * Carrega uma collecton
		 * 
		 * @param filter Objeto com os filtros a serem aplicados. Campo campo do objeto será usado como filtro no lado do servidor.
		 */
		public function load(filter:Object=null):AsyncToken {
			var f:Object;
			if( filter ) {
				f = filter;
			} else {
				f = this.defaultFilter;
			}
			return this.executeServiceCall( listService.loadList(this.modelName,f,this.managerName), loadResultHandler );
		}

		/**
		 * Carrega a collecton somente se nao estiver carregada
		 * 
		 * @param filter Objeto com os filtros a serem aplicados. Campo campo do objeto será usado como filtro no lado do servidor.
		 */
		public function loadIfNotLoad(filter:Object=null):void {
			if( ! this.collection ) {
				this.load(filter);
			}
		}
		
		public function empty():void {
			if( this.collection ) {
				this.collection.removeAll();
				this.collection = null;
			}
		}
		
		//--------------------------------------------------------------------------
		//
		//  Handler methods
		//
		//--------------------------------------------------------------------------
		
		
		[EventHandler(event='ListObjNameIdEvent.EVENT_LOAD',properties='aliasName,filter')]
		public function loadHandler( aliasName:String=null, filter:Object=null ):AsyncToken {
			if( this.aliasName == aliasName ) {
				return this.load( filter );
			}
			return null;
		}
		
		[EventHandler(event='ListObjNameIdEvent.EVENT_LOAD_FROM_OBJECT',properties='aliasName,obj,objField,objServerField')]
		public function loadFromObjectHandler( aliasName:String, obj:Object, objField:String, objServerField:String  ):AsyncToken {
			trace( 'Handler ListObjNameIdEvent.EVENT_LOAD_FROM_OBJECT: aliasName - ' + this.aliasName + ' event aliasName - ' + aliasName );
			if( this.aliasName == aliasName ) {
				return this.loadFromObject( obj, objField, objServerField );
			}
			return null;
		}
		
		public function loadResultHandler( event:ResultEvent ):void {
			this.collection = new ArrayCollection( event.result as Array );
			var e:ListObjNameIdEvent = new ListObjNameIdEvent( ListObjNameIdEvent.EVENT_LOAD_COMPLETE, this.aliasName );
			this.dispatcher.dispatchEvent( e );
		}
	}
}
